﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Noris.Tools.SystemResourceMonitor.UI
{
    public partial class SysResMonitorForm : Form
    {
        public SysResMonitorForm()
        {
            InitializeComponent();
            MonitorInit();
            SwitchInit();
            SampleInit();
            DirectoryInit();
            WindowInit();
        }
        #region Vztahy na monitor
        private void MonitorInit()
        {
            this.Monitor = new ResMonitor();
            this.Monitor.RunningChanged += new EventHandler(Monitor_RunningChanged);
            this.MonitorStop();
            this.RefreshRunningState(); 
        }
        /// <summary>
        /// Po změně stavu Running
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Monitor_RunningChanged(object sender, EventArgs e)
        {
            this.RefreshRunningState(); 
        }
        private void MonitorRun()
        {
            this.MonitorRunning = true;    // Set vyvolá událost RunningChanged => Monitor_RunningChanged() => RefreshRunningState()
            if (this.MonitorRunning)       // Hodnota odpovídá aktuálnímu stavu procesu (get), protože požadavek na true mohl být v (set) odmítnut.
                this._InfoLabel.Text = "";
            else
                this._InfoLabel.Text = this.Monitor.RunningInfo;
        }
        private void MonitorStop()
        {
            this.MonitorRunning = false;   // Set vyvolá událost RunningChanged => Monitor_RunningChanged() => RefreshRunningState()
        }
        /// <summary>
        /// Po změně stavu Running, z libovolného důvodu. Zde se provede reakce GUI na aktuální stav.
        /// </summary>
        private void RefreshRunningState()
        {
            bool isRunning = this.MonitorRunning;
            this._SwitchOnBtn.Value = isRunning;
            this._SwitchOffBtn.Value = !isRunning;
            this.RunMonitorItm.Image = (isRunning ? PicLibrary.DrawCircleGreen12_FromFile : PicLibrary.DrawCircleGray12_FromFile);
            this.StopMonitorItm.Image = (isRunning ? PicLibrary.DrawCircleGray12_FromFile : PicLibrary.DrawCircleRed12_FromFile);
            this._NotifyIcon.Text = (isRunning ? "Probíhá monitorování systému" : "Monitorování systému je vypnuto");
        }
        private ResMonitor Monitor;
        #endregion
        #region Property
        /// <summary>
        /// Příznak, zda monitor běží (přímá informace z monitoru)
        /// </summary>
        public bool MonitorRunning { get { return this.Monitor.Running; } set { this.Monitor.Running = value; } }
        public string MonitorTraceDirectory { get { return this.Monitor.TraceDirectory; } set { this.Monitor.TraceDirectory = value; } }
        public int MonitorInterval { get { return this.Monitor.Interval; } set { this.Monitor.Interval = value; } }
        #endregion
        #region Switch
        private void SwitchInit()
        {
            this._SwitchOnBtn.ImageFalseNormal = PicLibrary.CircleGreyNorm_FromFile;
            this._SwitchOnBtn.ImageFalseHot = PicLibrary.CircleGreyHot_FromFile;
            this._SwitchOnBtn.ImageFalsePressed = PicLibrary.ButtonGreenHot_FromFile;

            this._SwitchOnBtn.ImageTrueNormal = PicLibrary.ButtonGreenNorm_FromFile;
            this._SwitchOnBtn.ImageTrueHot = PicLibrary.ButtonGreenNorm_FromFile;
            this._SwitchOnBtn.ImageTruePressed = PicLibrary.ButtonGreenHot_FromFile;
            this._SwitchOnBtn.Click += new EventHandler(_SwitchOnBtn_Click);

            this._SwitchOffBtn.ImageFalseNormal = PicLibrary.CircleGreyNorm_FromFile;
            this._SwitchOffBtn.ImageFalseHot = PicLibrary.CircleGreyHot_FromFile;
            this._SwitchOffBtn.ImageFalsePressed = PicLibrary.ButtonRedHot_FromFile;

            this._SwitchOffBtn.ImageTrueNormal = PicLibrary.ButtonRedNorm_FromFile;
            this._SwitchOffBtn.ImageTrueHot = PicLibrary.ButtonRedNorm_FromFile;
            this._SwitchOffBtn.ImageTruePressed = PicLibrary.ButtonRedHot_FromFile;
            this._SwitchOffBtn.Click += new EventHandler(_SwitchOffBtn_Click);
        }
        private void _SwitchOnBtn_Click(object sender, EventArgs e)
        {
            this.MonitorRun();
        }
        private void _SwitchOffBtn_Click(object sender, EventArgs e)
        {
            this.MonitorStop();
        }
        #endregion
        #region Samples, Interval
        private void SampleInit()
        {
            this.SampleList = SampleInfo.CreateSampleList();
            this.SampleList.Sort((a, b) => a.Interval.CompareTo(b.Interval));
            this._IntervalTrack.Minimum = 0;
            this._IntervalTrack.Maximum = this.SampleList.Count - 1;
            this._IntervalTrack.TickFrequency = 1;

            int interval = this.MonitorInterval;
            int value = this.SampleList.FindIndex(s => s.Interval >= interval);
            if (value < 0)
                value = 7;
            this._IntervalTrack.Value = value;
            this._IntervalLabel.Text = this.SampleList[value].Text;

            this._IntervalTrack.ValueChanged += _IntervalTrackChanged;
        }
        private void _IntervalTrackChanged(object sender, EventArgs e)
        {
            SampleInfo sampleInfo = this.SampleList[this._IntervalTrack.Value];
            this._IntervalLabel.Text = sampleInfo.Text;
            this.MonitorInterval = sampleInfo.Interval;
        }
        protected class SampleInfo
        {
            #region Konstrukce, property
            private SampleInfo(int samples, int seconds)
            {
                this.Samples = samples;
                this.Seconds = seconds;
                this.Interval = 1000 * this.Seconds / this.Samples;
                this.Text = samples.ToString() + " " + GetText(samples, "záznam", "záznamy", "záznamů") + " za ";
                if (seconds < 60)
                {
                    this.Text += seconds.ToString() + " " + GetText(seconds, "sekundu", "sekundy", "sekund") + ".";
                }
                else
                {
                    int minutes = seconds / 60;
                    this.Text += minutes.ToString() + " " + GetText(minutes, "minutu", "minuty", "minut") + ".";
                }
            }
            internal int Samples { get; private set; }
            internal int Seconds { get; private set; }
            /// <summary>
            /// Interval v milisekundách
            /// </summary>
            internal int Interval { get; private set; }
            internal string Text { get; private set; }
            private static string GetText(int number, string txt1, string txt2, string txt5)
            {
                if (number == 1) return txt1;
                if (number < 1 || number > 4) return txt5;
                return txt2;
            }
            #endregion
            #region Seznam samplů
            internal static List<SampleInfo> CreateSampleList()
            {
                List<SampleInfo> result = new List<SampleInfo>();
                result.Add(new SampleInfo(10, 1));
                result.Add(new SampleInfo(8,1));
                result.Add(new SampleInfo(5,1));
                result.Add(new SampleInfo(4,1));
                result.Add(new SampleInfo(2,1));
                result.Add(new SampleInfo(1,1));
                result.Add(new SampleInfo(2,3));
                result.Add(new SampleInfo(1,2));
                result.Add(new SampleInfo(1,3));
                result.Add(new SampleInfo(1,4));
                result.Add(new SampleInfo(1,5));
                result.Add(new SampleInfo(1,10));
                result.Add(new SampleInfo(1,15));
                result.Add(new SampleInfo(1,20));
                result.Add(new SampleInfo(1,30));
                result.Add(new SampleInfo(1,60));
                result.Add(new SampleInfo(1,120));
                result.Add(new SampleInfo(1,180));
                result.Add(new SampleInfo(1,240));
                result.Add(new SampleInfo(1,300));
                result.Add(new SampleInfo(1,360));
                result.Add(new SampleInfo(1,600));
                result.Add(new SampleInfo(1,900));
                return result;
            }
            #endregion
        }
        private List<SampleInfo> SampleList;
        #endregion
        #region Output directory
        private void DirectoryInit()
        {
            this._DirText.Text = this.MonitorTraceDirectory;
        }
        private void _DirButton_Click(object sender, EventArgs e)
        {
            string directory = this.MonitorTraceDirectory;
            using (FolderBrowserDialog fbd = new FolderBrowserDialog())
            {
                fbd.Description = "Vyberte adresář, kam se mají ukládat monitorovací soubory:";
                fbd.RootFolder = Environment.SpecialFolder.MyComputer;
                fbd.SelectedPath = directory;
                fbd.ShowNewFolderButton = true;
                DialogResult result = fbd.ShowDialog(this);
                if (result == System.Windows.Forms.DialogResult.OK)
                {
                    this.MonitorTraceDirectory = fbd.SelectedPath;
                    this._DirText.Text = this.MonitorTraceDirectory;
                }
            }
        }
        #endregion
        #region Window
        private void WindowInit()
        {
            this._CloseButton.ImageFalseNormal = PicLibrary.ExitWGray_FromFile;
            this._CloseButton.ImageFalseHot = PicLibrary.ExitWHot_FromFile;
            this._CloseButton.ImageFalsePressed = PicLibrary.ExitWNorm_FromFile;
            this._CloseButton.Click += new EventHandler(_CloseButton_Click);
            this._MinButton.ImageFalseNormal = PicLibrary.DownWGray_FromFile;
            this._MinButton.ImageFalseHot = PicLibrary.DownWHot_FromFile;
            this._MinButton.ImageFalsePressed = PicLibrary.DownWNorm_FromFile;
            this._MinButton.Click += new EventHandler(_MinButton_Click);

            this._InfoLabel.Text = "";
            this.ShowInTaskbar = true;

            this.ShowMonitorItm.Image = PicLibrary.ApplicationXp16_FromFile;
            this.ShowMonitorItm.ImageScaling = ToolStripItemImageScaling.None;
            // this.RunMonitorItm.Image = PicLibrary.DrawCircleGray12_FromFile;      To už je nastaveno v metodě MonitorInit() => RefreshRunningState()
            this.RunMonitorItm.ImageScaling = ToolStripItemImageScaling.None;
            // this.StopMonitorItm.Image = PicLibrary.DrawCircleGray12_FromFile;
            this.StopMonitorItm.ImageScaling = ToolStripItemImageScaling.None;
            this.CloseAppItm.Image = PicLibrary.DialogClose12_FromFile;
            this.CloseAppItm.ImageScaling = ToolStripItemImageScaling.None;

            this._NotifyIcon.DoubleClick += new EventHandler(_NotifyIcon_DoubleClick);
            this._FormMoveSupport = new FormMoveSupport(this);
            this._FormMoveSupport.RegisterControl(this._SwitchOnBtn);
            this._FormMoveSupport.RegisterControl(this._SwitchOffBtn);
            this._FormMoveSupport.RegisterControl(this._InfoLabel);
            this._FormMoveSupport.RegisterControl(this._IntervalInfo);
            this._FormMoveSupport.RegisterControl(this._IntervalLabel);
            this._FormMoveSupport.RegisterControl(this._DirButton);
            this._FormMoveSupport.RegisterControl(this._DirText);
            this._FormMoveSupport.RegisterControl(this._CloseButton);
            this._FormMoveSupport.RegisterControl(this._MinButton);
        }
        void _NotifyIcon_DoubleClick(object sender, EventArgs e)
        {
            this.MainFormShow();
        }
        void _CloseButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        void _MinButton_Click(object sender, EventArgs e)
        {
            this.MainFormHide();
        }
        private void NotifyIconShow()
        {
            this._NotifyIcon.Visible = true;
        }
        private void NotifyIconHide()
        {
            this._NotifyIcon.Visible = false;
        }
        private void _ContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem.Name == this.ShowMonitorItm.Name)
                this.MainFormShow();
            else if (e.ClickedItem.Name == this.RunMonitorItm.Name)
                this.MonitorRun();
            else if (e.ClickedItem.Name == this.StopMonitorItm.Name)
                this.MonitorStop();
            else if (e.ClickedItem.Name == this.CloseAppItm.Name)
                this.MainFormExit();

        }
        private void MainFormShow()
        {
            this.ShowInTaskbar = true;
            this.Show();
            this.NotifyIconHide();
        }
        private void MainFormHide()
        {
            this.NotifyIconShow();
            this.ShowInTaskbar = false;
            this.Hide();
        }
        private void MainFormExit()
        {
            this.Close();
        }
        private FormMoveSupport _FormMoveSupport;
        #endregion
        
    }
}
